package cn.ycc1.baseset.basics;

import java.util.ArrayList;
import java.util.List;

/**
 * Control Flow Statements
 * @author ycc
 * @date 2025/3/3
 */
public class ControlFlow {

    /**
     * The If-Then Statement
     */
    public static void applyBrakes() {
        boolean isMoving = true;
        int currentSpeed = 10;

        // The If-Then Statement
        // the "if" clause: bicycle must be moving
        if (isMoving){
            // the "then" clause: decrease current speed
            currentSpeed--;
        }

        // The If-Then-Else Statement
        if (isMoving) {
            currentSpeed--;
        } else {
            System.err.println("The bicycle has already stopped!");
        }
    }

    /**
     * The If-Then-Else Statement
     */
    public static void ifElseDemo() {
        int testscore = 76;
        char grade;

        if (testscore >= 90) {
            grade = 'A';
        } else if (testscore >= 80) {
            grade = 'B';
        } else if (testscore >= 70) {
            grade = 'C';
        } else if (testscore >= 60) {
            grade = 'D';
        } else {
            grade = 'F';
        }
        System.out.println("Grade = " + grade);
    }

    /**
     * The While and Do-while Statements
     * while (true){
     *             // your code goes here
     *         }
     */
    public static void whileDemo() {
        int count = 1;
        while (count < 11) {
            System.out.println("Count is: " + count);
            count++;
        }
    }

    public static void doWhileDemo() {
        int count = 1;
        do {
            System.out.println("Count is: " + count);
            count++;
        } while (count < 11);
    }

    /**
     * The three expressions of the for loop are optional; an infinite loop can be created as follows:
     *
     * // infinite loop
     * for ( ; ; ) {
     *
     *     // your code goes here
     * }
     */
    public static void forDemo() {
        for(int i = 1; i < 11; i++){
            System.out.println("Count is: " + i);
        }
    }

    public static void enhancedForDemo() {
        int[] numbers =
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int item : numbers) {
            System.out.println("Count is: " + item);
        }
    }

    /**
     * The Break Statement
     */
    public static void breakDemo() {
        int[] arrayOfInts =
                { 32, 87, 3, 589,
                        12, 1076, 2000,
                        8, 622, 127 };
        int searchfor = 12;

        int i;
        boolean foundIt = false;

        for (i = 0; i < arrayOfInts.length; i++) {
            if (arrayOfInts[i] == searchfor) {
                foundIt = true;
                break;
            }
        }

        if (foundIt) {
            System.out.println("Found " + searchfor + " at index " + i);
        } else {
            System.out.println(searchfor + " not in the array");
        }
    }

    public static void breakWithLabelDemo() {
        int[][] arrayOfInts = {
                {  32,   87,    3, 589 },
                {  12, 1076, 2000,   8 },
                { 622,  127,   77, 955 }
        };
        int searchfor = 12;

        int i;
        int j = 0;
        boolean foundIt = false;

        search:
            for (i = 0; i < arrayOfInts.length; i++) {
                for (j = 0; j < arrayOfInts[i].length;
                     j++) {
                    if (arrayOfInts[i][j] == searchfor) {
                        foundIt = true;
                        break search;
                    }
                }
            }

            if (foundIt) {
                System.out.println("Found " + searchfor + " at " + i + ", " + j);
            } else {
                System.out.println(searchfor + " not in the array");
            }
    }

    public static void continueDemo() {
        String searchMe = "peter piper picked a " + "peck of pickled peppers";
        int max = searchMe.length();
        int numPs = 0;

        for (int i = 0; i < max; i++) {
            // interested only in p's
            if (searchMe.charAt(i) != 'p')
                continue;

            // process p's
            numPs++;
        }
        System.out.println("Found " + numPs + " p's in the string.");
    }

    public static void continueWithLabelDemo() {
        String searchMe = "Look for a substring in me";
        String substring = "sub";
        boolean foundIt = false;

        int max = searchMe.length() -
                substring.length();

        test:
            for (int i = 0; i <= max; i++) {
                int n = substring.length();
                int j = i;
                int k = 0;
                while (n-- != 0) {
                    if (searchMe.charAt(j++) != substring.charAt(k++)) {
                        continue test;
                    }
                }
                foundIt = true;
                break test;
            }
            System.out.println(foundIt ? "Found it" : "Didn't find it");
    }

    public static void switchDemo() {
        int quarter = 2; // any value

        String quarterLabel = null;
        switch (quarter) {
            case 0: quarterLabel = "Q1 - Winter";
                break;
            case 1: quarterLabel = "Q2 - Spring";
                break;
            case 2: quarterLabel = "Q2 - Summer";
                break;
            case 3: quarterLabel = "Q3 - Summer";
                break;
            default: quarterLabel = "Unknown quarter";
        };
    }

    public static void futureMonths() {
        int month = 8;
        List<String> futureMonths = new ArrayList<>();

        switch (month) {
            case 1:  futureMonths.add("January");
            case 2:  futureMonths.add("February");
            case 3:  futureMonths.add("March");
            case 4:  futureMonths.add("April");
            case 5:  futureMonths.add("May");
            case 6:  futureMonths.add("June");
            case 7:  futureMonths.add("July");
            case 8:  futureMonths.add("August");
            case 9:  futureMonths.add("September");
            case 10: futureMonths.add("October");
            case 11: futureMonths.add("November");
            case 12: futureMonths.add("December");
                break;
            default: break;
        }
    }

    public static void multipleCaseLabels() {
        int month = 2;
        int year = 2021;
        int numDays = 0;

        switch (month) {
            case 1: case 3: case 5:   // January March May
            case 7: case 8: case 10:  // July August October
            case 12:
                numDays = 31;
                break;
            case 4: case 6:   // April June
            case 9: case 11:  // September November
                numDays = 30;
                break;
            case 2: // February
                if (((year % 4 == 0) &&
                        !(year % 100 == 0))
                        || (year % 400 == 0))
                    numDays = 29;
                else
                    numDays = 28;
                break;
            default:
                System.out.println("Invalid month.");
                break;
        }
    }

    public static void choosingBetween() {
        int month = 2; // any month
        if (month == 1) {
            System.out.println("January");
        } else if (month == 2) {
            System.out.println("February");
        }  // and so on

        int temperature = 60; // any temperature
        if (temperature < 0) {
            System.out.println("Water is ice");
        } else if (temperature < 100){
            System.out.println("Water is liquid, known as water");
        } else {
            System.out.println("Water is vapor");
        }

    }

    /**
     * Using String as a Type for the Case Labels
     * @param
     */
    public static void stringType() {
        String month = "september"; // any month
        int monthNumber = -1;

        switch (month.toLowerCase()) {
            case "january":
                monthNumber = 1;
                break;
            case "february":
                monthNumber = 2;
                break;
            case "march":
                monthNumber = 3;
                break;
            case "april":
                monthNumber = 4;
                break;
            case "may":
                monthNumber = 5;
                break;
            case "june":
                monthNumber = 6;
                break;
            case "july":
                monthNumber = 7;
                break;
            case "august":
                monthNumber = 8;
                break;
            case "september":
                monthNumber = 9;
                break;
            case "october":
                monthNumber = 10;
                break;
            case "november":
                monthNumber = 11;
                break;
            case "december":
                monthNumber = 12;
                break;
            default:
                monthNumber = 0;
                break;
        }
    }

    public static void modifies() {
//        Day day = MONDAY; // any day
//        int len = 0;
//        switch (day) {
//            case MONDAY:
//            case FRIDAY:
//            case SUNDAY:
//                len = 6;
//                break;
//            case TUESDAY:
//                len = 7;
//                break;
//            case THURSDAY:
//            case SATURDAY:
//                len = 8;
//                break;
//            case WEDNESDAY:
//                len = 9;
//                break;
//        }
//        System.out.println("len = " + len);
    }

    public static void expression() {
//        Day day = ...; // any day
//        int len =
//                switch (day) {
//                    case MONDAY, FRIDAY, SUNDAY -> 6;
//                    case TUESDAY                -> 7;
//                    case THURSDAY, SATURDAY     -> 8;
//                    case WEDNESDAY              -> 9;
//                };
//        System.out.println("len = " + len);
    }

    // Be careful, this code does NOT compile!
//    public static String convertToLabel(int quarter) {
//         String quarterLabel =
//                switch (quarter) {
//                    case 0  -> {
//                        System.out.println("Q1 - Winter");
//                        return "Q1 - Winter";
//                    }
//                    default -> "Unknown quarter";
//                };
//        return quarterLabel;
//    }

    // Be careful, this code does NOT compile!
//    public String convertToLabel(int quarter) {
//        String quarterLabel =
//                switch (quarter) {
//                    case 0  -> {
//                        System.out.println("Q1 - Winter");
//                        return "Q1 - Winter";
//                    }
//                    default -> "Unknown quarter";
//                };
//        return quarterLabel;
//    }
    public String convertToLabel(int quarter) {
        String quarterLabel =
            switch (quarter) {
                case 0  -> {
                    System.out.println("Q1 - Winter");
                    yield "Q1 - Winter";
                }
                default -> "Unknown quarter";
            };
        return quarterLabel;
    }
    public static void colonCase() {
        int quarter = 0; // any value

        String quarterLabel =
                switch (quarter) {
                    case 0 :  yield "Q1 - Winter";
                    case 1 :  yield "Q2 - Spring";
                    case 2 :  yield "Q3 - Summer";
                    case 3 :  yield "Q3 - Summer";
                    default: System.out.println("Unknown quarter");
                        yield "Unknown quarter";
                };
    }
    public static void main(String[] args) {
        enhancedForDemo();

        // The Return Statement
        // return ++count;
        // When a method is declared void, use the form of return that doesn't return a value.
        return;
    }
}
